﻿using DBUtil.Attributes;
using DotNetCommon.Extensions;
using NUnit.Framework;
using Shouldly;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace Test.MySql.JsonTests
{
    [TestFixture]
    internal class JsonStoreTests2 : TestBase
    {
        [Table("test")]
        public class TUser
        {
            [PrimaryKey(KeyStrategy = KeyStrategy.Identity)]
            [Column("id")]
            public int Id { get; set; }

            [Column("name")]
            [JsonStore(Bucket = "properties", Key = "name")]
            public string Name { get; set; }

            [Column("age")]
            [JsonStore(Bucket = "properties2", Key = "age")]
            public int Age { get; set; }

            [Column("birth")]
            [JsonStore(Bucket = "properties2", Key = "birth")]
            public DateTime? Birth { get; set; }

            [Column("addrs")]
            [JsonStore(Bucket = "properties", Key = "addrs")]
            public List<string> Addrs { get; set; }
        }

        [Test]
        public void Test()
        {
            var dt = DateTime.Parse("1990-01-02 01:02:03");
            var sql = "";

            DropTableIfExist("test");
            db.ExecuteSql(@"create table test(id int auto_increment primary key,properties json,properties2 json)");

            db.Insert<TUser>().SetEntity(new[]
             {
                new TUser
                {
                    Name="test",
                    Age=1,
                    Birth=dt,
                    Addrs=new List<string>(){"hah"}
                }
            }).ExecuteAffrows();

            sql = db.Update<TUser>().SetEntity(new TUser
            {
                Id = 1,
                Age = 18,
                Name = "小明",
                Birth = dt,
                Addrs = new List<string> { "天明路", "清华路" }
            }).ToSql();
            //sql.ShouldBe("""
            //    update test set
            //        properties = json_set(ifnull(properties,json_object()),
            //            '$."name"','小明',
            //            '$."addrs"',cast('["天明路","清华路"]' as json)),
            //        properties2 = json_set(ifnull(properties2,json_object()),
            //            '$."age"',18,
            //            '$."birth"','1990-01-02T01:02:03.0000000')
            //    where id = 1;
            //    """);
            db.ExecuteSql(sql);
            var ent = db.Select<TUser>().Where(i => i.Id == 1).FirstOrDefault();
            ent.Age.ShouldBe(18);
            ent.Birth.ShouldBe(dt);
            ent.Addrs.ToJson().ShouldBe(new List<string> { "天明路", "清华路" }.ToJson());
        }

        [Test]
        public void TestSet()
        {
            string sql = "";
            sql = db.Update<TUser>().SetColumnExpr(i => i.Name, "小明").Where(i => i.Id == 1).ToSql();
            //sql.ShouldBe("""
            //    update test set
            //        properties = json_set(ifnull(properties,json_object()),
            //            '$."name"','小明')
            //    where id = 1;
            //    """);

            sql = db.Update<TUser>().SetColumnExpr(i => i.Name, i => i.Name + "2").Where(i => i.Id == 1).ToSql();
            //sql.ShouldBe("""
            //    update test set
            //        properties = json_set(ifnull(properties,json_object()),
            //            '$."name"',concat_ws('',json_value(properties,'$."name"' returning char),'2'))
            //    where id = 1;
            //    """);

            sql = db.Update<TUser>().SetColumnExpr(i => i.Addrs, i => i.Addrs.AddFluent("桃园")).Where(i => i.Id == 1).ToSql();
            //sql.ShouldBe("""
            //    update test set
            //        properties = json_set(ifnull(properties,json_object()),
            //            '$."addrs"',json_array_append(ifnull(json_value(properties,'$."addrs"'),'[]'),'$','桃园'))
            //    where id = 1;
            //    """);

            sql = db.Update<TUser>().SetColumnExpr(i => i.Addrs, i => i.Addrs.ClearFluent().AddFluent("桃园")).Where(i => i.Id == 1).ToSql();
            //sql.ShouldBe("""
            //    update test set
            //        properties = json_set(ifnull(properties,json_object()),
            //            '$."addrs"',json_array_append(json_array(),'$','桃园'))
            //    where id = 1;
            //    """);
        }
    }
}
